Introducción al Manejo de Datos en R con {tidyverse}

R para Ciencia de Datos en Salud:
Análisis Descriptivo e Inferencia Estadística

Percy Soto-Becerra M.D., M.Sc(c)

InkaStats Data Science Solutions | Medical Branch
@github/psotob91

El Operador Pipe

%>%

Fuente: Sesion2-Introduccion a R y RStudio. Andre Valle y Steev Loyola Enlace

Operadar %>% en acción

Esto de aquí:

getwd()
[1] "D:/OneDrive/GitHub/r4hds-curso3-inkstat2/slides/sesion1"
mis_datos <- read_stata("maca_meno_fase1.dta") 
mis_datos <- as_factor(mis_datos)

Se puede simplificar a esto:

mis_datos <- read_stata("maca_meno_fase1.dta") %>% 
  as_factor()

Principios del manejo de datos con {dplyr}

Librería dplyr

  • El paquete dplyr es una ‘suite’ de funciones para manipular dato

Filtrado de datos con filter()

  • Extrae filas que cumplen cierta condición lógica

Filtrado de datos con filter() y comparadores

Filtrado de datos con filter() y booleanos

Filtrado de datos con filter() - ejemplo

  • Se tienen los datos originales:
datos_fase1 <- read_stata("maca_meno_fase1.dta") %>% 
  as_factor()

datos_fase1
# A tibble: 106 × 14
      id time  treat   age race  married married2 procedence weight height    e2
   <dbl> <fct> <fct> <dbl> <chr> <fct>   <fct>    <chr>       <dbl>  <dbl> <dbl>
 1     1 Base… Plac…    33 Mest… Single  Without… Callao       59      1.4  87.3
 2     1 3 mo… Plac…    32 Mest… Single  Without… Callao       59.9    1.3 210. 
 3     2 Base… Dosi…    27 Mest… Single  Without… Santa Ani…   62      1.5 169. 
 4     2 3 mo… Dosi…    27 Mest… Single  Without… Santa Ani…   62.1    1.6  99.9
 5     3 Base… Dosi…    25 Mest… Single  Without… Callao       62      1.6  78.8
 6     3 3 mo… Dosi…    25 Mest… Single  Without… Callao       60      1.6 155. 
 7     4 Base… Dosi…    37 Mest… Divorc… Without… Callao       60.9    1.5  41.0
 8     4 3 mo… Dosi…    38 Mest… Divorc… Without… Callao       61.4    1.5 109. 
 9     5 Base… Plac…    31 Mest… Single  Without… La Molina    64      1.5  43.0
10     5 3 mo… Plac…    32 Mest… Single  Without… La Molina    58.1    1.6  56.0
# … with 96 more rows, and 3 more variables: lh <dbl>, fsh <dbl>, prog <dbl>
  • Si se filtra solo para tener a los individuos en su medición basal:
datos_fase1 %>% 
  filter(time == "Baseline")
# A tibble: 53 × 14
      id time  treat   age race  married married2 procedence weight height    e2
   <dbl> <fct> <fct> <dbl> <chr> <fct>   <fct>    <chr>       <dbl>  <dbl> <dbl>
 1     1 Base… Plac…    33 Mest… Single  Without… Callao       59      1.4  87.3
 2     2 Base… Dosi…    27 Mest… Single  Without… Santa Ani…   62      1.5 169. 
 3     3 Base… Dosi…    25 Mest… Single  Without… Callao       62      1.6  78.8
 4     4 Base… Dosi…    37 Mest… Divorc… Without… Callao       60.9    1.5  41.0
 5     5 Base… Plac…    31 Mest… Single  Without… La Molina    64      1.5  43.0
 6     6 Base… Plac…    38 Mest… Married With co… Los Olivos   54.5    1.5  36.2
 7     7 Base… Dosi…    26 Mest… Married With co… SMP          59.1    1.6  91.3
 8     8 Base… Plac…    34 Mest… Married With co… Carabayllo   64      1.5  65.6
 9     9 Base… Dosi…    30 Mest… Single  Without… SMP          61      1.6  49.6
10    10 Base… Plac…    38 Mest… Single  Without… Pueblo Li…   56.1    1.7 115. 
# … with 43 more rows, and 3 more variables: lh <dbl>, fsh <dbl>, prog <dbl>
  • Podemos querer filtrar a los individuos en la medición basal Y que sean placebo:
datos_fase1 %>% 
  filter(time == "Baseline" & treat == "PLACEBO")
# A tibble: 0 × 14
# … with 14 variables: id <dbl>, time <fct>, treat <fct>, age <dbl>,
#   race <chr>, married <fct>, married2 <fct>, procedence <chr>, weight <dbl>,
#   height <dbl>, e2 <dbl>, lh <dbl>, fsh <dbl>, prog <dbl>
  • Podemos querer filtrar a los individuos en la medición basal O que sean placebo:
datos_fase1 %>% 
  filter(time == "Baseline" | treat == "PLACEBO")
# A tibble: 53 × 14
      id time  treat   age race  married married2 procedence weight height    e2
   <dbl> <fct> <fct> <dbl> <chr> <fct>   <fct>    <chr>       <dbl>  <dbl> <dbl>
 1     1 Base… Plac…    33 Mest… Single  Without… Callao       59      1.4  87.3
 2     2 Base… Dosi…    27 Mest… Single  Without… Santa Ani…   62      1.5 169. 
 3     3 Base… Dosi…    25 Mest… Single  Without… Callao       62      1.6  78.8
 4     4 Base… Dosi…    37 Mest… Divorc… Without… Callao       60.9    1.5  41.0
 5     5 Base… Plac…    31 Mest… Single  Without… La Molina    64      1.5  43.0
 6     6 Base… Plac…    38 Mest… Married With co… Los Olivos   54.5    1.5  36.2
 7     7 Base… Dosi…    26 Mest… Married With co… SMP          59.1    1.6  91.3
 8     8 Base… Plac…    34 Mest… Married With co… Carabayllo   64      1.5  65.6
 9     9 Base… Dosi…    30 Mest… Single  Without… SMP          61      1.6  49.6
10    10 Base… Plac…    38 Mest… Single  Without… Pueblo Li…   56.1    1.7 115. 
# … with 43 more rows, and 3 more variables: lh <dbl>, fsh <dbl>, prog <dbl>
  • Si queremos solo las mujeres entre 34 y 38 años de edad:
datos_fase1 %>% 
  filter(age >= 34 & age <= 38)
# A tibble: 36 × 14
      id time  treat   age race  married married2 procedence weight height    e2
   <dbl> <fct> <fct> <dbl> <chr> <fct>   <fct>    <chr>       <dbl>  <dbl> <dbl>
 1     4 Base… Dosi…    37 Mest… Divorc… Without… Callao       60.9    1.5  41.0
 2     4 3 mo… Dosi…    38 Mest… Divorc… Without… Callao       61.4    1.5 109. 
 3     6 Base… Plac…    38 Mest… Married With co… Los Olivos   54.5    1.5  36.2
 4     6 3 mo… Plac…    38 Mest… Married With co… Los Olivos   53.9    1.5  44.7
 5     8 Base… Plac…    34 Mest… Married With co… Carabayllo   64      1.5  65.6
 6     8 3 mo… Plac…    34 Mest… Married With co… Carabayllo   59      1.5 134. 
 7    10 Base… Plac…    38 Mest… Single  Without… Pueblo Li…   56.1    1.7 115. 
 8    10 3 mo… Plac…    38 Mest… Single  Without… Pueblo Li…   54.9    1.5  71.5
 9    11 Base… Dosi…    37 Mest… Married With co… El Agusti…   72      1.6  66.4
10    11 3 mo… Dosi…    36 Mest… Married With co… El Agusti…   NA     NA   110. 
# … with 26 more rows, and 3 more variables: lh <dbl>, fsh <dbl>, prog <dbl>
  • Si queremos a quienes son de Santa Anita, Callao, SMP o Carabayllo:

Opción válida pero ineficiente:

datos_fase1 %>% 
  filter(procedence == "Santa Anita" | procedence == "Callao" | procedence == "SMP" | procedence == "Carabayllo")
# A tibble: 24 × 14
      id time  treat   age race  married married2 procedence weight height    e2
   <dbl> <fct> <fct> <dbl> <chr> <fct>   <fct>    <chr>       <dbl>  <dbl> <dbl>
 1     1 Base… Plac…    33 Mest… Single  Without… Callao       59      1.4  87.3
 2     1 3 mo… Plac…    32 Mest… Single  Without… Callao       59.9    1.3 210. 
 3     2 Base… Dosi…    27 Mest… Single  Without… Santa Ani…   62      1.5 169. 
 4     2 3 mo… Dosi…    27 Mest… Single  Without… Santa Ani…   62.1    1.6  99.9
 5     3 Base… Dosi…    25 Mest… Single  Without… Callao       62      1.6  78.8
 6     3 3 mo… Dosi…    25 Mest… Single  Without… Callao       60      1.6 155. 
 7     4 Base… Dosi…    37 Mest… Divorc… Without… Callao       60.9    1.5  41.0
 8     4 3 mo… Dosi…    38 Mest… Divorc… Without… Callao       61.4    1.5 109. 
 9     7 Base… Dosi…    26 Mest… Married With co… SMP          59.1    1.6  91.3
10     7 3 mo… Dosi…    26 Mest… Married With co… SMP          58.6    1.6  91.3
# … with 14 more rows, and 3 more variables: lh <dbl>, fsh <dbl>, prog <dbl>

Opción válida y eficiente:

datos_fase1 %>% 
  filter(procedence %in% c("Santa Anita", "Callao", "SMP", "Carabayllo"))
# A tibble: 24 × 14
      id time  treat   age race  married married2 procedence weight height    e2
   <dbl> <fct> <fct> <dbl> <chr> <fct>   <fct>    <chr>       <dbl>  <dbl> <dbl>
 1     1 Base… Plac…    33 Mest… Single  Without… Callao       59      1.4  87.3
 2     1 3 mo… Plac…    32 Mest… Single  Without… Callao       59.9    1.3 210. 
 3     2 Base… Dosi…    27 Mest… Single  Without… Santa Ani…   62      1.5 169. 
 4     2 3 mo… Dosi…    27 Mest… Single  Without… Santa Ani…   62.1    1.6  99.9
 5     3 Base… Dosi…    25 Mest… Single  Without… Callao       62      1.6  78.8
 6     3 3 mo… Dosi…    25 Mest… Single  Without… Callao       60      1.6 155. 
 7     4 Base… Dosi…    37 Mest… Divorc… Without… Callao       60.9    1.5  41.0
 8     4 3 mo… Dosi…    38 Mest… Divorc… Without… Callao       61.4    1.5 109. 
 9     7 Base… Dosi…    26 Mest… Married With co… SMP          59.1    1.6  91.3
10     7 3 mo… Dosi…    26 Mest… Married With co… SMP          58.6    1.6  91.3
# … with 14 more rows, and 3 more variables: lh <dbl>, fsh <dbl>, prog <dbl>


Selección de columnas con select()

  • La función select() selecciona columnas

  • El signo - permite elegir qué columnas eliminar.

  • A veces es mejor llamarla usando: dplyr::select() debido a que otros paquetes también tienen una función con el mismo nombre select()

Selección de columnas con select() - ejemplo

  • Los datos originales:
datos_fase1
# A tibble: 106 × 14
      id time  treat   age race  married married2 procedence weight height    e2
   <dbl> <fct> <fct> <dbl> <chr> <fct>   <fct>    <chr>       <dbl>  <dbl> <dbl>
 1     1 Base… Plac…    33 Mest… Single  Without… Callao       59      1.4  87.3
 2     1 3 mo… Plac…    32 Mest… Single  Without… Callao       59.9    1.3 210. 
 3     2 Base… Dosi…    27 Mest… Single  Without… Santa Ani…   62      1.5 169. 
 4     2 3 mo… Dosi…    27 Mest… Single  Without… Santa Ani…   62.1    1.6  99.9
 5     3 Base… Dosi…    25 Mest… Single  Without… Callao       62      1.6  78.8
 6     3 3 mo… Dosi…    25 Mest… Single  Without… Callao       60      1.6 155. 
 7     4 Base… Dosi…    37 Mest… Divorc… Without… Callao       60.9    1.5  41.0
 8     4 3 mo… Dosi…    38 Mest… Divorc… Without… Callao       61.4    1.5 109. 
 9     5 Base… Plac…    31 Mest… Single  Without… La Molina    64      1.5  43.0
10     5 3 mo… Plac…    32 Mest… Single  Without… La Molina    58.1    1.6  56.0
# … with 96 more rows, and 3 more variables: lh <dbl>, fsh <dbl>, prog <dbl>
  • Si solo quiero seleccionar a id, time, age, race y procedence:
datos_fase1_seleccionados <- datos_fase1 %>% 
  select(id, time, age, race, procedence)

datos_fase1_seleccionados 
# A tibble: 106 × 5
      id time       age race    procedence 
   <dbl> <fct>    <dbl> <chr>   <chr>      
 1     1 Baseline    33 Mestiza Callao     
 2     1 3 months    32 Mestiza Callao     
 3     2 Baseline    27 Mestiza Santa Anita
 4     2 3 months    27 Mestiza Santa Anita
 5     3 Baseline    25 Mestiza Callao     
 6     3 3 months    25 Mestiza Callao     
 7     4 Baseline    37 Mestiza Callao     
 8     4 3 months    38 Mestiza Callao     
 9     5 Baseline    31 Mestiza La Molina  
10     5 3 months    32 Mestiza La Molina  
# … with 96 more rows
  • Si quisiera excluir a procedence:
datos_fase1_seleccionados %>% 
  select(-procedence) #notar el signo -
# A tibble: 106 × 4
      id time       age race   
   <dbl> <fct>    <dbl> <chr>  
 1     1 Baseline    33 Mestiza
 2     1 3 months    32 Mestiza
 3     2 Baseline    27 Mestiza
 4     2 3 months    27 Mestiza
 5     3 Baseline    25 Mestiza
 6     3 3 months    25 Mestiza
 7     4 Baseline    37 Mestiza
 8     4 3 months    38 Mestiza
 9     5 Baseline    31 Mestiza
10     5 3 months    32 Mestiza
# … with 96 more rows

Podemos anidar con %>% varias tareas

datos_fase1 %>% 
  filter(age > 35) %>% # Primero filtro por age
  select(id, time, treat, race, age) # Luego me quedo solo con estas 5 columnas
# A tibble: 40 × 5
      id time     treat   race      age
   <dbl> <fct>    <fct>   <chr>   <dbl>
 1     4 Baseline Dosis 1 Mestiza    37
 2     4 3 months Dosis 1 Mestiza    38
 3     6 Baseline Placebo Mestiza    38
 4     6 3 months Placebo Mestiza    38
 5    10 Baseline Placebo Mestiza    38
 6    10 3 months Placebo Mestiza    38
 7    11 Baseline Dosis 2 Mestiza    37
 8    11 3 months Dosis 2 Mestiza    36
 9    15 Baseline Placebo Mestiza    37
10    15 3 months Placebo Mestiza    37
# … with 30 more rows

Creación de nuevas columnas con mutate()

  • La función mutate() crea nuevas columnas en base a otras.

Creación de nuevas columnas con mutate() - ejemplo

  • Si queremos crear la variable índice de masa corporal:
datos_fase1 %>% 
  select(id, weight, height) %>% # Nos quedamos con peso y talla 
  mutate(imc = weight / height ^ 2) # Creamos IMC en base a peso y talla
# A tibble: 106 × 4
      id weight height   imc
   <dbl>  <dbl>  <dbl> <dbl>
 1     1   59      1.4  30.1
 2     1   59.9    1.3  35.4
 3     2   62      1.5  27.6
 4     2   62.1    1.6  24.3
 5     3   62      1.6  24.2
 6     3   60      1.6  23.4
 7     4   60.9    1.5  27.1
 8     4   61.4    1.5  27.3
 9     5   64      1.5  28.4
10     5   58.1    1.6  22.7
# … with 96 more rows

Modificación de columnas existentes con mutate()

  • mutate() también remplaza columnas existentes.

  • Tener cuidado si se quiere reutilizar la variable original, en ese caso es mejor crear columna nueva.

Modificación de columnas existentes con mutate() - ejemplo

  • Queremos que la edad sea reportada en meses:

Podríamos crear una columna nueva para edad en meses:

datos_fase1 %>% 
  select(id, age) %>% 
  mutate(age2 = age * 12) # Notar que se creó una columa nueva llamada age2
# A tibble: 106 × 3
      id   age  age2
   <dbl> <dbl> <dbl>
 1     1    33   396
 2     1    32   384
 3     2    27   324
 4     2    27   324
 5     3    25   300
 6     3    25   300
 7     4    37   444
 8     4    38   456
 9     5    31   372
10     5    32   384
# … with 96 more rows

La otra opción es remplazar la edad:

datos_fase1 %>% 
  select(id, age) %>% 
  mutate(age = age * 12) # Notar que se remplazó age 
# A tibble: 106 × 2
      id   age
   <dbl> <dbl>
 1     1   396
 2     1   384
 3     2   324
 4     2   324
 5     3   300
 6     3   300
 7     4   444
 8     4   456
 9     5   372
10     5   384
# … with 96 more rows

Categorización de variables con case_when()

  • Función de apoyo a mutate().

  • Categoriza variables de acuerdo a condiciones complejas

Categorización de variables con case_when()-ejemplo

  • Se quieren crear categorías de edad: 20-30, 31-35 y 36-41
datos_fase1 %>% 
  select(id, age) %>% 
  mutate(agecat = case_when(age >= 20 & age <= 30 ~ "20-30", 
                            age >= 31 & age <= 35 ~ "31-35", 
                            age >= 36 & age <= 41 ~ "36-41", 
                            TRUE ~ as.character(NA))) # Siempre cerrar con esto
# A tibble: 106 × 3
      id   age agecat
   <dbl> <dbl> <chr> 
 1     1    33 31-35 
 2     1    32 31-35 
 3     2    27 20-30 
 4     2    27 20-30 
 5     3    25 20-30 
 6     3    25 20-30 
 7     4    37 36-41 
 8     4    38 36-41 
 9     5    31 31-35 
10     5    32 31-35 
# … with 96 more rows

Etiquetar variables con set_var_labels()

  • La función set_var_labels() del paquete labelled() es muy útil para etiquetar columnas.

  • Los datos deben tener metadatos que permitan ser legibles por el ser humano.

  • Esta función debería ser usada al final de todo el proceso.

Etiquetar variables con set_var_labels()

  • Veamos un ejemplo:

  • Ahora pongamos una etiqueta:
library(labelled)
datos2 <- datos %>% 
  set_variable_labels(
    pam = "Presión Arterial Media", 
    pas = "Presión Arterial Sistólica", 
    pad = "Presión Arterial Diastólica"
  )